package com.greyshark.lib.bluetooth.parse

import android.R
import com.google.gson.Gson
import com.google.gson.GsonBuilder
import com.greyshark.lib.bluetooth.ControlCenterClient
import com.greyshark.lib.bluetooth.ProtocolCommand
import com.greyshark.lib.bluetooth.callback.CommonResultInfoCallback
import com.greyshark.lib.bluetooth.callback.query.BatteryInfoCallback
import com.greyshark.lib.bluetooth.callback.query.BloodOxygenCallback
import com.greyshark.lib.bluetooth.callback.query.DailyInfoCallback
import com.greyshark.lib.bluetooth.callback.query.DaySleepCallback
import com.greyshark.lib.bluetooth.callback.query.DeviceInfoCallback
import com.greyshark.lib.bluetooth.callback.query.EffectiveStandCallback
import com.greyshark.lib.bluetooth.callback.query.HealthInfoCallback
import com.greyshark.lib.bluetooth.callback.query.HeartRateCallback
import com.greyshark.lib.bluetooth.callback.query.LightingInfoCallback
import com.greyshark.lib.bluetooth.callback.query.LightingNotDisturbInfoCallback
import com.greyshark.lib.bluetooth.callback.query.NightSleepCallback
import com.greyshark.lib.bluetooth.callback.query.RealTimeSportCallback
import com.greyshark.lib.bluetooth.callback.query.SportRecordCallback
import com.greyshark.lib.bluetooth.callback.query.SupportFunctionCallback
import com.greyshark.lib.bluetooth.callback.query.TemperatureCallback
import com.greyshark.lib.bluetooth.callback.query.UserInfoCallback
import com.greyshark.lib.bluetooth.core.CallbackManager
import com.greyshark.lib.bluetooth.entity.Packet
import com.greyshark.lib.bluetooth.entity.query.DailyDataEntity
import com.greyshark.lib.bluetooth.entity.query.DaySleepEntity
import com.greyshark.lib.bluetooth.entity.query.DeviceInfoEntity
import com.greyshark.lib.bluetooth.entity.query.EffectiveStandEntity
import com.greyshark.lib.bluetooth.entity.query.HealthInfoEntity
import com.greyshark.lib.bluetooth.entity.query.LightingInfoEntity
import com.greyshark.lib.bluetooth.entity.query.NightSleepEntity
import com.greyshark.lib.bluetooth.entity.query.RealTimeSportInfoEntity
import com.greyshark.lib.bluetooth.entity.query.SportRecordInfoEntity
import com.greyshark.lib.bluetooth.entity.query.SupportFunctionEntity
import com.greyshark.lib.bluetooth.entity.query.UserInfoEntity
import com.greyshark.lib.bluetooth.extensions.toHex
import com.greyshark.lib.bluetooth.utils.BleLogger
import com.greyshark.lib.bluetooth.utils.ByteHexUtils
import com.greyshark.lib.bluetooth.utils.LogUtils
import com.greyshark.lib.bluetooth.utils.TimeoutManager
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.Job
import kotlinx.coroutines.channels.Channel
import kotlinx.coroutines.flow.MutableSharedFlow
import kotlinx.coroutines.launch
import java.io.ByteArrayOutputStream
import java.nio.ByteBuffer
import java.nio.ByteOrder
import java.util.concurrent.ConcurrentHashMap

const val KEY_TIMEOUT_QUERY_DEVICE_INFO = "TIMEOUT_KEY_QUERY_DEVICE_INFO"
const val KEY_TIMEOUT_QUERY_BATTERY_INFO = "KEY_TIMEOUT_QUERY_BATTERY_INFO"
const val KEY_TIMEOUT_QUERY_USER_INFO = "KEY_TIMEOUT_QUERY_USER_INFO"
const val KEY_TIMEOUT_QUERY_SUPPORT_FUNCTION = "KEY_TIMEOUT_QUERY_SUPPORT_FUNCTION"
const val KEY_TIMEOUT_QUERY_REALTIME_SPORT_INFO = "KEY_TIMEOUT_QUERY_REALTIME_SPORT_INFO"
const val KEY_TIMEOUT_QUERY_HEART_RATE = "KEY_TIMEOUT_QUERY_HEART_RATE"
const val KEY_TIMEOUT_QUERY_BLOOD_OXYGEN = "KEY_TIMEOUT_QUERY_BLOOD_OXYGEN"
const val KEY_TIMEOUT_QUERY_TEMPERATURE = "KEY_TIMEOUT_QUERY_TEMPERATURE"

const val KEY_TIMEOUT_QUERY_DAILY_INFO = "KEY_TIMEOUT_QUERY_DAILY_INFO"
const val KEY_TIMEOUT_QUERY_HEALTH_INFO = "KEY_TIMEOUT_QUERY_HEALTH_INFO"
const val KEY_TIMEOUT_QUERY_NIGHT_SLEEP_INFO = "KEY_TIMEOUT_QUERY_NIGHT_SLEEP_INFO"
const val KEY_TIMEOUT_QUERY_DAY_SLEEP_INFO = "KEY_TIMEOUT_QUERY_DAY_SLEEP_INFO"
const val KEY_TIMEOUT_QUERY_EFFECTIVE_STANDING_INFO = "KEY_TIMEOUT_QUERY_EFFECTIVE_STANDING_INFO"
const val KEY_TIMEOUT_QUERY_SPORT_RECORD_INFO = "KEY_TIMEOUT_QUERY_SPORT_RECORD_INFO"
const val KEY_TIMEOUT_QUERY_LIGHTING_INFO = "KEY_TIMEOUT_QUERY_LIGHTING_INFO"
const val KEY_TIMEOUT_QUERY_LIGHTING_NOT_DISTURB_INFO = "KEY_TIMEOUT_QUERY_LIGHTING_NOT_DISTURB_INFO"

const val KEY_TIMEOUT_SYNC_TIME = "KEY_TIMEOUT_SYNC_TIME"
const val KEY_TIMEOUT_SYNC_APP_STATUS = "KEY_TIMEOUT_SYNC_APP_STATUS"
const val KEY_TIMEOUT_SYNC_LIGHTING = "KEY_TIMEOUT_SYNC_LIGHTING"
const val KEY_TIMEOUT_SYNC_USER_INFO = "KEY_TIMEOUT_SYNC_USER_INFO"
const val KEY_TIMEOUT_SYNC_SPORT_STATUS = "KEY_TIMEOUT_SYNC_SPORT_STATUS"

const val KEY_TIMEOUT_SYNC_LIGHTING_NOT_DISTURB_INFO = "KEY_TIMEOUT_SYNC_LIGHTING_NOT_DISTURB_INFO"


class PacketParse {
  private val tag = PacketParse::class.java.simpleName

  val responseFlow = MutableSharedFlow<Int>(extraBufferCapacity = 10)
  private val ioScope = CoroutineScope(Dispatchers.IO + Job())

  companion object {
    val instance: PacketParse by lazy(mode = LazyThreadSafetyMode.SYNCHRONIZED) {
      PacketParse()
    }
  }

  fun startTimeout(key: String, timeout: Long) {
    TimeoutManager.instance.startTimeout(key, timeout) {
      when (key) {
        KEY_TIMEOUT_QUERY_DEVICE_INFO -> {
          deviceInfoCallback?.onTimeout()
        }

        KEY_TIMEOUT_QUERY_BATTERY_INFO -> {
          batteryInfoCallback?.onTimeout()
        }

        KEY_TIMEOUT_QUERY_USER_INFO -> {
          userInfoCallback?.onTimeout()
        }

        KEY_TIMEOUT_QUERY_SUPPORT_FUNCTION -> {
          supportFunctionCallback?.onTimeout()
        }

        KEY_TIMEOUT_QUERY_REALTIME_SPORT_INFO -> {
          realTimeSportCallback?.onTimeout()
        }

        KEY_TIMEOUT_QUERY_HEART_RATE -> {
          heartRateCallback?.onTimeout()
        }

        KEY_TIMEOUT_QUERY_BLOOD_OXYGEN -> {
          bloodOxygenCallback?.onTimeout()
        }

        KEY_TIMEOUT_QUERY_TEMPERATURE -> {
          temperatureCallback?.onTimeout()
        }

        KEY_TIMEOUT_QUERY_DAILY_INFO -> {
          dailyInfoCallback?.onTimeout()
        }

        KEY_TIMEOUT_QUERY_HEALTH_INFO -> {
          healthInfoCallback?.onTimeout()
        }

        KEY_TIMEOUT_QUERY_NIGHT_SLEEP_INFO -> {
          nightSleepCallback?.onTimeout()
        }

        KEY_TIMEOUT_QUERY_DAY_SLEEP_INFO -> {
          daySleepCallback?.onTimeout()
        }

        KEY_TIMEOUT_QUERY_EFFECTIVE_STANDING_INFO -> {
          effectiveStandCallback?.onTimeout()
        }

        KEY_TIMEOUT_QUERY_SPORT_RECORD_INFO -> {
          sportRecordCallback?.onTimeout()
        }

        KEY_TIMEOUT_SYNC_TIME -> {
          timeSyncCallback?.onTimeout()
        }

        KEY_TIMEOUT_SYNC_LIGHTING -> {
          lightingSyncCallback?.onTimeout()
        }

        KEY_TIMEOUT_SYNC_USER_INFO -> {
          userInfoSyncCallback?.onTimeout()
        }

        KEY_TIMEOUT_SYNC_APP_STATUS -> {
          appStatusSyncCallback?.onTimeout()
        }

        KEY_TIMEOUT_SYNC_SPORT_STATUS -> {
          sportStatusSyncCallback?.onTimeout()
        }


        KEY_TIMEOUT_SYNC_LIGHTING_NOT_DISTURB_INFO -> {
          lightingNotDisturbSyncCallback?.onTimeout()
        }
        else -> {}
      }
    }
  }

  fun stopTimeout(key: String) {
    TimeoutManager.instance.cancelTimeout(key)
  }

  internal var deviceInfoQueryTimeout = 5_000L
  internal var deviceInfoCallback: DeviceInfoCallback? = null

  internal var batteryInfoQueryTimeout = 5_000L
  internal var batteryInfoCallback: BatteryInfoCallback? = null

  internal var userInfoQueryTimeout = 5_000L
  internal var userInfoCallback: UserInfoCallback? = null

  internal var supportFunctionQueryTimeout = 5_000L
  internal var supportFunctionCallback: SupportFunctionCallback? = null

  internal var realTimeSportQueryTimeout = 5_000L
  internal var realTimeSportReportTimeout = 5_000L
  internal var realTimeSportCallback: RealTimeSportCallback? = null

  internal var heartRateQueryTimeout = 5_000L
  internal var heartRateReportTimeout = 5_000L
  internal var heartRateCallback: HeartRateCallback? = null

  internal var bloodOxygenQueryTimeout = 5_000L
  internal var bloodOxygenReportTimeout = 5_000L
  internal var bloodOxygenCallback: BloodOxygenCallback? = null

  internal var temperatureQueryTimeout = 5_000L
  internal var temperatureReportTimeout = 5_000L
  internal var temperatureCallback: TemperatureCallback? = null

  internal var dailyInfoQueryTimeout = 5_000L
  internal var dailyInfoCallback: DailyInfoCallback? = null

  internal var healthInfoQueryTimeout = 5_000L
  internal var healthInfoCallback: HealthInfoCallback? = null

  internal var nightSleepQueryTimeout = 5_000L
  internal var nightSleepCallback: NightSleepCallback? = null

  internal var daySleepQueryTimeout = 5_000L
  internal var daySleepCallback: DaySleepCallback? = null

  internal var effectiveStandQueryTimeout = 5_000L
  internal var effectiveStandCallback: EffectiveStandCallback? = null

  internal var sportRecordQueryTimeout = 5_000L
  internal var sportRecordCallback: SportRecordCallback? = null

  internal var lightingInfoQueryTimeout = 5_000L
  internal var lightingInfoCallback: LightingInfoCallback? = null


  internal var lightingNotDisturbInfoQueryTimeout = 5_000L
  internal var lightingNotDisturbInfoCallback: LightingNotDisturbInfoCallback? = null


  internal var timeSyncTimeout = 5_000L
  internal var timeSyncCallback: CommonResultInfoCallback? = null

  internal var lightingSyncTimeout = 5_000L
  internal var lightingSyncCallback: CommonResultInfoCallback? = null

  internal var userInfoSyncTimeout = 5_000L
  internal var userInfoSyncCallback: CommonResultInfoCallback? = null

  internal var appStatusSyncTimeout = 5_000L
  internal var appStatusSyncCallback: CommonResultInfoCallback? = null

  internal var sportStatusSyncTimeout = 5_000L
  internal var sportStatusSyncCallback: CommonResultInfoCallback? = null

  internal var lightingNotDisturbSyncTimeout = 5_000L
  internal var lightingNotDisturbSyncCallback: CommonResultInfoCallback? = null


  private val gson: Gson = GsonBuilder().create()

  // 读取 little-endian 的 2 字节 Int
  fun readLittleEndianInt(bytes: ByteArray, offset: Int): Int {
    return ByteBuffer.wrap(bytes, offset, 2)
      .order(ByteOrder.LITTLE_ENDIAN)
      .short
      .toInt() and 0xFFFF
  }

  private val packetMap = ConcurrentHashMap<Int, MutableList<Packet>>()

  // 解析单个包
  fun parsePacket(bytes: ByteArray) {
    CallbackManager.dataPacketCallback?.onResult(System.currentTimeMillis(), bytes)
    if (bytes.size < 14) {
      return
    }

    val start = readLittleEndianInt(bytes, 0)
    val end = readLittleEndianInt(bytes, bytes.size - 2)
    LogUtils.e(tag, "packet start = $start,${start.toHexString()}; end = $end,${end.toHexString()}")

    val type = readLittleEndianInt(bytes, 2)
    val total = readLittleEndianInt(bytes, 4)
    val current = readLittleEndianInt(bytes, 6)
    val dataLength = readLittleEndianInt(bytes, 8)
    LogUtils.e(tag, "type=$type,total=$total,current=$current,dataLength=$dataLength")

    val expectedSize = 10 + dataLength + 4
    LogUtils.e(tag, "receive data length = ${bytes.size}, parse data length is $expectedSize")
    if (bytes.size != expectedSize) {
      return
    }
    if (current < 1 || current > total) {
      return
    }

    val data = if (bytes.size == 14) {
      byteArrayOf()
    } else {
      bytes.copyOfRange(10, 10 + dataLength)
    }
    val packet = Packet(type, total, current, data, bytes)
    if (total == 1) {
      combineData(type, arrayListOf(packet))
      LogUtils.i(tag, "responseChannel trySend true 1")
      return
    }
    if (packetMap.containsKey(type)) {
      packetMap.get(type)!!.add(packet)
      LogUtils.i(tag, "packetMap value size = ${packetMap.get(type)!!.size}")
      if (packetMap[type]!!.size == total) {
        combineData(type, packetMap[type]!!)
        packetMap.get(type)!!.clear()
        packetMap.remove(type)
        LogUtils.i(tag, "responseChannel trySend true 2")
        //结束超时
      }
    } else {
      packetMap.put(type, arrayListOf())
      packetMap.get(type)!!.add(packet)
      LogUtils.i(tag, "packetMap value size = ${packetMap.get(type)!!.size}")
      //开启超时
    }
  }

  private fun combineData(type: Int, list: MutableList<Packet>) {
    val absoluteStream = ByteArrayOutputStream()
    for ((index, item) in list.withIndex()) {
      val filterList = list.filter {
        it.current == index + 1
      }
      if (filterList.size != 1) {
        continue
      }
      absoluteStream.write(filterList.first().data)
    }
    val absoluteBytes = absoluteStream.toByteArray()
    parsePacketData(type, absoluteBytes)
    ioScope.launch {
      responseFlow.emit(type)
    }
  }

  private fun parsePacketData(type: Int, dataPacket: ByteArray) {
    when (type) {
      in 0x0100..0x01ff -> parseQueryPacketData(type, dataPacket)
      in 0x0200..0x02ff -> parseSettingPacketData(type, dataPacket)
      in 0x0300..0x03ff -> parseActiveReportingPacketData(type, dataPacket)
      else -> {}
    }
  }

  private fun parseQueryPacketData(type: Int, dataPacket: ByteArray) {
    BleLogger.i(tag, "parseQueryPacketData data:${dataPacket.size}, type:${type.toHexString()}")
    when (type) {
      //上报 查询设备信息
      0x0101 -> {
        stopTimeout(KEY_TIMEOUT_QUERY_DEVICE_INFO)
        try {
          val entity = DeviceInfoEntity(
            name = String(dataPacket.copyOfRange(0, 16).reversed().toByteArray()),
            productModel = dataPacket.copyOfRange(16, 22)
              .joinToString("") { "%02X".format(it) },
            //type = dataPacket.copyOfRange(16, 22).toHex().toInt(),
            firmwareVersion = dataPacket.copyOfRange(22, 24).toHex().toInt(),
            hardwareVersion = dataPacket.copyOfRange(24, 30).toHex().toInt(),
            serialNumber = dataPacket.copyOfRange(30, 46).toHex().toInt(),
            protocolVersion = dataPacket.copyOfRange(46, 50).toHex().toInt(),
          )
          deviceInfoCallback?.onData(entity)
          LogUtils.i(tag, "device info json=${gson.toJson(entity)}")
        } catch (e: Exception) {
          deviceInfoCallback?.onError(e.message.toString())
          LogUtils.e(tag, "device error info=${e.message}")
        }
      }

      //上报 查询电量信息
      0x0102 -> {
        stopTimeout(KEY_TIMEOUT_QUERY_BATTERY_INFO)
        try {
          val battery = dataPacket[0].toInt()
          val isCharge = dataPacket[1].toInt() == 2
          batteryInfoCallback?.onData(battery, isCharge)
          LogUtils.i(tag, "device battery=$battery, isCharge=$isCharge")
        } catch (e: Exception) {
          batteryInfoCallback?.onError(e.message.toString())
          LogUtils.e(tag, "device error battery=${e.message}")
        }
      }

      //上报 查询⽤户信息
      0x0103 -> {
        stopTimeout(KEY_TIMEOUT_QUERY_USER_INFO)
        try {
          val entity = UserInfoEntity(
            weight = dataPacket.copyOfRange(0, 2).toHex().toInt(),
            height = dataPacket.copyOfRange(2, 4).toHex().toInt(),
            sex = dataPacket[4].toInt() == 0,
            birthday = dataPacket.copyOfRange(5, 11).toHex()
          )
          userInfoCallback?.onData(entity)
          LogUtils.i(tag, "user info json:${gson.toJson(entity)}")
        } catch (e: Exception) {
          userInfoCallback?.onError(e.message.toString())
          LogUtils.e(tag, "user error info=${e.message}")
        }
      }

      //上报 查询健康信息
      0x0104 -> {
        stopTimeout(KEY_TIMEOUT_QUERY_HEALTH_INFO)
        try {
          val entityList = arrayListOf<HealthInfoEntity>()
          for (index in 0 until dataPacket.size / 16) {
            val entity = HealthInfoEntity(
              time = dataPacket.copyOfRange(index * 16, index * 16 + 6).toHex(),
              heartRate = dataPacket.copyOfRange(index * 16 + 6, index * 16 + 8).toHex().toInt(),
              temperature = dataPacket.copyOfRange(index * 16 + 8, index * 16 + 10).toHex()
                .toInt() / 10,
              heartRateVariability = dataPacket[index * 16 + 10].toInt(),
              bloodOxygen = dataPacket.copyOfRange(index * 16 + 11, index * 16 + 13).toHex()
                .toInt(),
              pressure = dataPacket[index * 16 + 13].toInt(),
              activityIntensity = dataPacket[index * 16 + 14].toInt(),
              respiratoryRate = dataPacket[index * 16 + 15].toInt(),
            )
            entityList.add(entity)
          }
          healthInfoCallback?.onData(entityList)
          LogUtils.i(tag, "health info size:${entityList.size}")
          LogUtils.i(tag, "health info json:${gson.toJson(entityList)}")
        } catch (e: Exception) {
          healthInfoCallback?.onError(e.message.toString())
          LogUtils.e(tag, "health error info=${e.message}")
        }
      }

      //上报 查询夜间睡眠信息
      0x0105 -> {
        stopTimeout(KEY_TIMEOUT_QUERY_NIGHT_SLEEP_INFO)
        try {
          val length = 8
          val entityList = arrayListOf<NightSleepEntity>()
          for (index in 0 until dataPacket.size / length) {
            val entity = NightSleepEntity(
              startTime = dataPacket.copyOfRange(index * length, index * length + 6).toHex(),
              quality = dataPacket[index * length + 6].toInt(),
              activityIntensity = dataPacket[index * length + 7].toInt(),
            )
            entityList.add(entity)
          }
          nightSleepCallback?.onData(entityList)
          LogUtils.i(tag, "night sleep info size:${entityList.size}")
          LogUtils.i(tag, "night sleep info json:${gson.toJson(entityList)}")
        } catch (e: Exception) {
          nightSleepCallback?.onError(e.message.toString())
          LogUtils.e(tag, "night sleep error info=${e.message}")
        }
      }

      //上报 查询白天睡眠信息
      0x0106 -> {
        stopTimeout(KEY_TIMEOUT_QUERY_DAY_SLEEP_INFO)
        try {
          val length = 12
          val entityList = arrayListOf<DaySleepEntity>()
          for (index in 0 until dataPacket.size / length) {
            val entity = DaySleepEntity(
              startTime = dataPacket.copyOfRange(index * length, index * length + 6).toHex(),
              endTime = dataPacket.copyOfRange(index * length + 6, index * length + 12).toHex(),
            )
            entityList.add(entity)
          }
          daySleepCallback?.onData(entityList)
          LogUtils.i(tag, "day sleep info size:${entityList.size}")
          LogUtils.i(tag, "day sleep info json:${gson.toJson(entityList)}")
        } catch (e: Exception) {
          daySleepCallback?.onError(e.message.toString())
          LogUtils.e(tag, "day sleep error info=${e.message}")
        }
      }

      //上报 查询运动信息
      0x0107 -> {
        stopTimeout(KEY_TIMEOUT_QUERY_SPORT_RECORD_INFO)
        try {
          val length = 36
          val entityList = arrayListOf<SportRecordInfoEntity>()
          val newDataPacket = dataPacket
          for (index in 0 until dataPacket.size / length) {
            val entity = SportRecordInfoEntity(
              sportIndex = newDataPacket[index * length].toInt(),
              startTime = newDataPacket.copyOfRange(index * length + 1, index * length + 7)
                .toHex(),
              endTime = newDataPacket.copyOfRange(index * length + 7, index * length + 13)
                .toHex(),
              sportType = newDataPacket[index * length + 13].toInt(),
              nowTime = newDataPacket.copyOfRange(index * length + 14, index * length + 20)
                .toHex(),
              sportDuration = newDataPacket.copyOfRange(index * length + 20, index * length + 22)
                .toHex()
                .toInt(),
              totalStep = newDataPacket.copyOfRange(index * length + 22, index * length + 24)
                .toHex()
                .toInt(),
              totalCalories = newDataPacket.copyOfRange(index * length + 24, index * length + 26)
                .toHex()
                .toInt(),
              totalDistance = newDataPacket.copyOfRange(index * length + 26, index * length + 30)
                .toHex()
                .toInt(),
              nowHeartRate = newDataPacket.copyOfRange(index * length + 30, index * length + 32)
                .toHex()
                .toInt(),
              nowTemperature = newDataPacket.copyOfRange(index * length + 32, index * length + 34)
                .toHex()
                .toInt(),
              nowBloodOxygen = newDataPacket.copyOfRange(index * length + 34, index * length + 36)
                .toHex()
                .toInt(),
              cadence = if (index == 0) {
                0
              } else {
                val step = newDataPacket.copyOfRange(index * length + 22, index * length + 24)
                  .toHex()
                  .toInt()
                val duration = newDataPacket.copyOfRange(index * length + 20, index * length + 22)
                  .toHex()
                  .toInt()
                val durationDiff = (duration - entityList.last().sportDuration) * 60
                if (durationDiff != 0) {
                  (step - entityList.last().totalStep) / durationDiff
                } else {
                  0 // 避免除零异常
                }
              },
              speed = if (index == 0) {
                0.0
              } else {
                val distance = newDataPacket.copyOfRange(index * length + 26, index * length + 30)
                  .toHex()
                  .toInt()
                val duration = newDataPacket.copyOfRange(index * length + 20, index * length + 22)
                  .toHex()
                  .toInt()
                val durationDiff = (duration - entityList.last().sportDuration) * 3.6
                if (durationDiff != 0.0) {
                  (distance - entityList.last().totalDistance) / durationDiff
                } else {
                  0.0 // 避免除零异常
                }
              },
              pace = if (index == 0) {
                0.0
              } else {
                val distance = newDataPacket.copyOfRange(index * length + 26, index * length + 30)
                  .toHex()
                  .toInt()
                val duration = newDataPacket.copyOfRange(index * length + 20, index * length + 22)
                  .toHex()
                  .toInt()
                val distanceDiff = distance - entityList.last().totalDistance
                if (distanceDiff != 0) {
                  (duration - entityList.last().sportDuration) / distanceDiff * 1000.0
                } else {
                  0.0 // 避免除零异常
                }
              },
            )
            entityList.add(entity)
          }
          sportRecordCallback?.onData(entityList)
          LogUtils.i(tag, "sport record info size:${entityList.size}")
          LogUtils.i(tag, "sport record info json:${Gson().toJson(entityList)}")
        } catch (e: Exception) {
          sportRecordCallback?.onError(e.message.toString())
          LogUtils.e(tag, "sport record error info=${e.message}")
        }
      }

      //上报 是否主动上报实时运动信息
      0x0108 -> {
        stopTimeout(KEY_TIMEOUT_QUERY_REALTIME_SPORT_INFO)
        try {
          val realSportStatus = dataPacket[0].toInt()
          realTimeSportCallback?.onData(realSportStatus)
          LogUtils.i(tag, "realtime sport status=${realSportStatus}")
        } catch (e: Exception) {
          realTimeSportCallback?.onError(e.message.toString())
          LogUtils.e(tag, "realtime sport error status=${e.message}")
        }
      }

      //上报 查询站⽴信息命令
      0x0109 -> {
        stopTimeout(KEY_TIMEOUT_QUERY_EFFECTIVE_STANDING_INFO)
        try {
          val length = 12
          val entityList = arrayListOf<EffectiveStandEntity>()
          for (index in 0 until dataPacket.size / length) {
            val entity = EffectiveStandEntity(
              startTime = dataPacket.copyOfRange(index * length, index * length + 6).toHex(),
              endTime = dataPacket.copyOfRange(index * length + 6, index * length + 12).toHex(),
            )
            entityList.add(entity)
          }
          effectiveStandCallback?.onData(entityList)
          LogUtils.i(tag, "effective stand info size:${entityList.size}")
          LogUtils.i(tag, "effective stand info json:${gson.toJson(entityList)}")
        } catch (e: Exception) {
          effectiveStandCallback?.onError(e.message.toString())
          LogUtils.e(tag, "effective stand error info=${e.message}")
        }
      }

      //上报 是否主动上报实时⼼率/⾎氧/体温信息
      0x01A0 -> {
        stopTimeout(KEY_TIMEOUT_QUERY_HEART_RATE)
        stopTimeout(KEY_TIMEOUT_QUERY_BLOOD_OXYGEN)
        stopTimeout(KEY_TIMEOUT_QUERY_TEMPERATURE)
        try {
          when (dataPacket[0].toInt()) {
            0x01 -> {
              val status = dataPacket[1].toInt()
              heartRateCallback?.onData(status)
              LogUtils.i(tag, "heart rate status=$status")
            }

            0x02 -> {
              val status = dataPacket[1].toInt()
              bloodOxygenCallback?.onData(status)
              LogUtils.i(tag, "blood oxygen status=$status")
            }

            0x03 -> {
              val status = dataPacket[1].toInt()
              temperatureCallback?.onData(status)
              LogUtils.i(tag, "temperature status=$status")
            }

            else -> {}
          }
        } catch (e: Exception) {
          when (dataPacket[0].toInt()) {
            0x01 -> {
              heartRateCallback?.onError(e.message.toString())
              LogUtils.i(tag, "heart rate error status=${e.message}")
            }

            0x02 -> {
              bloodOxygenCallback?.onError(e.message.toString())
              LogUtils.i(tag, "blood oxygen error status=${e.message}")
            }

            0x03 -> {
              temperatureCallback?.onError(e.message.toString())
              LogUtils.i(tag, "temperature error status=${e.message}")
            }

            else -> {}
          }
        }
      }

      //上报 查询⽀持功能
      0x01A1 -> {
        stopTimeout(KEY_TIMEOUT_QUERY_SUPPORT_FUNCTION)
        try {
          val ints = ByteHexUtils.instance.byteToIntArray(dataPacket[0])
          val entity = SupportFunctionEntity()
          entity.apply {
            isSupportSport = ints[0] == 1
            isSupportLighting = ints[1] == 1
            isSupportHeartRate = ints[2] == 1
            isSupportBloodOxygen = ints[3] == 1
            isSupportTemperature = ints[4] == 1
          }
          supportFunctionCallback?.onData(entity)
          LogUtils.i(tag, "support function json=${gson.toJson(ints)}")
        } catch (e: Exception) {
          supportFunctionCallback?.onError(e.message.toString())
          LogUtils.e(tag, "support function error info=${e.message}")
        }
      }

      //上报 查询⽇常数据信息
      0x01A2 -> {
        stopTimeout(KEY_TIMEOUT_QUERY_DAILY_INFO)
        try {
          val entityList = arrayListOf<DailyDataEntity>()
          for (index in 0 until dataPacket.size / 16) {
            val dailyDataEntity = DailyDataEntity(
              time = dataPacket.copyOfRange(index * 16, index * 16 + 6).toHex(),
              totalDuration = dataPacket.copyOfRange(index * 16 + 6, index * 16 + 8).toHex()
                .toInt(),
              totalStep = dataPacket.copyOfRange(index * 16 + 8, index * 16 + 10).toHex().toInt(),
              totalCalories = dataPacket.copyOfRange(index * 16 + 10, index * 16 + 12).toHex()
                .toInt(),
              totalDistance = dataPacket.copyOfRange(index * 16 + 12, index * 16 + 16).toHex()
                .toInt(),
            )
            entityList.add(dailyDataEntity)
          }
          dailyInfoCallback?.onData(entityList)
          LogUtils.i(tag, "daily info size:${entityList.size}")
          LogUtils.i(tag, "daily info json:${gson.toJson(entityList)}")
        } catch (e: Exception) {
          dailyInfoCallback?.onError(e.message.toString())
          LogUtils.e(tag, "daily error info=${e.message}")
        }
      }

      //上报mtu大小
      0x01A3 -> {
        val mtu = dataPacket[0].toInt()
        LogUtils.i(tag, "query mtu size is $mtu")
        ControlCenterClient.instance.chanceMTU(185)
      }

      //上报灯光信息
      0x01A4 -> {
        stopTimeout(KEY_TIMEOUT_QUERY_LIGHTING_INFO)
        try {
          val entityList = arrayListOf<LightingInfoEntity>()
          val length = 10
          for (index in 0 until dataPacket.size / length) {
            val dailyDataEntity = LightingInfoEntity(
              index = dataPacket[index * length].toUByte().toInt(),        // 序列号
              switch = dataPacket[index * length + 1].toUByte().toInt() == 1, // 开关
              mode = dataPacket[index * length + 2].toUByte().toInt(),     // 模式
              rgb = dataPacket.copyOfRange(index * length + 3, index * length + 6).toHex(), // RGB
              brightness = dataPacket[index * length + 6].toUByte().toInt(), // 亮度
              speed = dataPacket[index * length + 7].toUByte().toInt(),     // 速度
              duration = dataPacket[index * length + 8].toUByte().toInt(),  // 持续时长
              interval = dataPacket[index * length + 9].toUByte().toInt(),  // 间隔
            )
            entityList.add(dailyDataEntity)
          }
          lightingInfoCallback?.onData(entityList)
          LogUtils.i(tag, "lighting info size:${entityList.size}")
          LogUtils.i(tag, "lighting info json:${gson.toJson(entityList)}")
        } catch (e: Exception) {
          lightingInfoCallback?.onError(e.message.toString())
          LogUtils.e(tag, "lighting error info=${e.message}")
        }
      }

      //上报灯效免打扰设置信息
      0x01A5 -> {
        stopTimeout(KEY_TIMEOUT_QUERY_LIGHTING_NOT_DISTURB_INFO)
        try {
          // 根据协议解析免打扰设置数据，数据长度为5字节
          val switch = dataPacket[0].toUByte().toInt() == 1  // 免打扰开关 (1:开启, 2:关闭)
          val startHour = dataPacket[1].toUByte().toInt()    // 开始时间-时 (0-23)
          val startMin = dataPacket[2].toUByte().toInt()     // 开始时间-分 (0-59)
          val endHour = dataPacket[3].toUByte().toInt()      // 结束时间-时 (0-23)
          val endMin = dataPacket[4].toUByte().toInt()       // 结束时间-分 (0-59)
          lightingNotDisturbInfoCallback?.onData(switch = switch,startHour=startHour,startMin=startMin,endHour=endHour,endMin=endMin)
          LogUtils.i(tag, "lighting not disturb info: switch=$switch, start=${startHour}:${startMin}, end=${endHour}:${endMin}")
        } catch (e: Exception) {
          lightingNotDisturbInfoCallback?.onError(e.message.toString())
          LogUtils.e(tag, "lighting not disturb error info=${e.message}")
        }
      }

      else -> {}
    }
  }

  private fun parseSettingPacketData(type: Int, dataPacket: ByteArray) {
    BleLogger.i(tag, "parseSettingPacketData")
    when (type) {
      0x0201 -> {
        stopTimeout(KEY_TIMEOUT_SYNC_TIME)
        val statusCode = dataPacket[0].toInt()
        userInfoSyncCallback?.onData(statusCode)
        LogUtils.i(tag, "sync time status code:${statusCode}")
      }

      0x0202 -> {
        stopTimeout(KEY_TIMEOUT_SYNC_LIGHTING)
        val statusCode = dataPacket[0].toInt()
        lightingSyncCallback?.onData(statusCode)
        LogUtils.i(tag, "sync lighting status code:${statusCode}")
      }

      0x0205 -> {
        stopTimeout(KEY_TIMEOUT_SYNC_USER_INFO)
        val statusCode = dataPacket[0].toInt()
        userInfoSyncCallback?.onData(statusCode)
        LogUtils.i(tag, "sync user info status code:${statusCode}")
      }

      0x0206 -> {
        stopTimeout(KEY_TIMEOUT_SYNC_SPORT_STATUS)
        val statusCode = dataPacket[0].toInt()
        sportStatusSyncCallback?.onData(statusCode)
        LogUtils.i(tag, "sync sport status code:${statusCode}")
      }

      0x0207 -> {
        stopTimeout(KEY_TIMEOUT_SYNC_APP_STATUS)
        val statusCode = dataPacket[0].toInt()
        appStatusSyncCallback?.onData(statusCode)
        LogUtils.i(tag, "sync app status code:${statusCode}")
      }

      0x0203 -> {
        stopTimeout(KEY_TIMEOUT_SYNC_LIGHTING_NOT_DISTURB_INFO)
        val statusCode = dataPacket[0].toInt()
        lightingNotDisturbSyncCallback?.onData(statusCode)
        LogUtils.i(tag, "sync lighting not disturb code:${statusCode}")
      }
      else -> {}
    }
  }

  private fun parseActiveReportingPacketData(type: Int, dataPacket: ByteArray) {
    BleLogger.i(tag, "parseActiveReportingPacketData")
    when (type) {
      0x0301 -> {
        CallbackManager.reportSportInfoCallback?.onData(dataPacket[0].toUInt().toInt())
        ControlCenterClient.instance.sendCommand(ProtocolCommand.appConfirm())
      }

      0x0302 -> {
        CallbackManager.reportRealTimeInfoCallback?.onData(dataPacket[0].toUInt().toInt())
        ControlCenterClient.instance.sendCommand(ProtocolCommand.appConfirm())
      }

      0x0303 -> {
        val entity = RealTimeSportInfoEntity(
          startTime = dataPacket.copyOfRange(0, 6).toHex(),
          sportType = dataPacket[6].toUInt().toInt(),
          nowTime = dataPacket.copyOfRange(7, 13).toHex(),
          sportDuration = dataPacket.copyOfRange(13, 15).toHex().toInt(),
          totalStep = dataPacket.copyOfRange(15, 17).toHex().toInt(),
          totalCalories = dataPacket.copyOfRange(17, 19).toHex().toInt(),
          totalDistance = dataPacket.copyOfRange(19, 23).toHex().toInt(),
          nowHeartRate = dataPacket.copyOfRange(23, 25).toHex().toInt(),
          nowTemperature = dataPacket.copyOfRange(25, 27).toHex().toInt(),
          nowBloodOxygen = dataPacket.copyOfRange(27, 29).toHex().toInt(),
        )
        CallbackManager.reportRealTimeSportInfoCallback?.onData(entity)
        LogUtils.i(tag, "report sport = ${gson.toJson(entity)}")
      }

      0x0304 -> {
        when (dataPacket[0].toInt()) {
          //心率
          0x01 -> {
            val hr = dataPacket.copyOfRange(1, 5).toHex().toInt()
            CallbackManager.reportRealTimeHealthInfoCallback?.onDataByHeartRate(hr)
            LogUtils.i(tag, "report hr = $hr")
            ControlCenterClient.instance.sendCommand(ProtocolCommand.appConfirm())
          }
          //血氧
          0x02 -> {
            val bo = dataPacket.copyOfRange(1, 5).toHex().toInt()
            CallbackManager.reportRealTimeHealthInfoCallback?.onDataByBloodOxygen(bo)
            LogUtils.i(tag, "report bo = $bo")
            ControlCenterClient.instance.sendCommand(ProtocolCommand.appConfirm())
          }
          //体温
          0x03 -> {
            val t = dataPacket.copyOfRange(1, 5).toHex().toInt()
            CallbackManager.reportRealTimeHealthInfoCallback?.onDataByTemperature(t)
            LogUtils.i(tag, "report temperature = $t")
            ControlCenterClient.instance.sendCommand(ProtocolCommand.appConfirm())
          }

          else -> {}
        }
      }

      0x0305 -> {
        CallbackManager.reportRealTimeBatteryInfoCallback?.onData(
          battery = dataPacket[0].toUInt().toInt(),
          isCharge = dataPacket[1].toUInt().toInt() == 2
        )
        ControlCenterClient.instance.sendCommand(ProtocolCommand.appConfirm())
      }

      else -> {}
    }
  }

}